home *** CD-ROM | disk | FTP | other *** search
- /*
- Explosion Sprites
- this is the code for handling the animated explosions in ZAM.
-
- */
- #include "ZAM.h"
- #include "SpriteFrameRates.h"
- #include "GameSounds.h"
- #include "ZAMProtos.h"
-
- #define kFirstExpFrameNum 0
- #define kLastExpFrameNum 5
-
- spritePtr GetExplosionSprite(gamePtr game);
-
- /* these are the globals used by this file. They are private to this file */
- /* other parts of the game deal with explosions by calling the routines in this file */
-
- static spriteLayerPtr gExplosionLayer;
- static spritePtr gExplosionSprite[kMaxExp];
-
- void StartExplosionHere(gamePtr game, Fixed h, Fixed v)
- /*
- This is the main explosion generation routine. When you want one,
- just call this and pass the fixed point coordinates, and an explosion will
- start. The game parameter is not really used any more, but the explosion list
- used to be kept in it.
- */
- {
- spritePtr thisExp;
-
- thisExp = GetExplosionSprite(game);
-
- if(thisExp != nil) {
- thisExp->visible = false;
- SetSpriteCurrentFrame(thisExp,0);
- SetSpriteLoc(thisExp, h, v);
- thisExp->visible = true;
- (void)PlaySndAsynchChannel( kExplode, kExplosionChan, kStdPriority);
- StartSpriteAction(thisExp);
- }
- }
-
-
- spritePtr GetExplosionSprite(gamePtr game)
- /*
- this function returns a spritePtr that is to be used for a new
- explosion. At one time I had an elaborate queueing scheme the prevented searching a list,
- but then I simplified it in order to reduce complexity and track down bugs in other parts of
- the code.
-
- */
- {
- short i;
-
- for(i = 0; i < kMaxExp; i++) {
- if(!gExplosionSprite[i]->inUse) {
- gExplosionSprite[i]->inUse = true;
- return gExplosionSprite[i];
- }
- }
-
- return nil;
- }
-
- Boolean ExplosionLastFrameProc(spritePtr expSprite, frameCellPtr frame)
- /*
- On the last frame of animation we want to hide the explosion
- so it erases properly, so explosion sprites are created with a frame callback
- on the last frame of animation.
- */
- {
-
- expSprite->visible = false; // hide it
- expSprite->inUse = false; // free it up
- StopSpriteAction(expSprite); // stop its clock
- expSprite->spriteFlags |= kNeedsToBeErased; // flag it for updating
- expSprite->ownerLayer->layerFlags |= kLayerDirty; // be sure the layer is flagged too
-
- return false; // don't want to be re-inserted in timer
- }
-
-
- Boolean FirstFrameProc(spritePtr explosionSprite, frameCellPtr frame)
- /*
- Make sure the sprite is visible on the first frame of animation.
- I forget why I do this, I think it was because of problems when one explosion was
- cancelled to start a new one.
- */
- {
- explosionSprite->visible = true; // just make sure we are visible
- return true;
- }
-
-
- void StartExplosionMoving(gamePtr game, Fixed h, Fixed v, fixPt *vel)
- /*
- This routine was used when I wanted the explosions to drift around
- but I don't use it anymore. The explosions will move though if you
- replace StartExplosionHere with this. Pretty handy.
- */
-
- {
- spritePtr thisExp;
-
- thisExp = GetExplosionSprite(game);
-
- if(thisExp == nil) { /* no more free explosions */
- ErrMsg("\pNo More Explosions are available");
- } else {
- thisExp->visible = false;
- /* prevent any drawing */
- StopSpriteAction(thisExp);
- SetSpriteCurrentFrame(thisExp,0);
- SetSpriteLoc(thisExp, h, v);
- SetSpriteVelocity(thisExp, vel->h >> 1, vel->v >> 1);
- thisExp->moveTimeInterval = 100;
-
- thisExp->visible = true;
- StartSpriteAction(thisExp);
- }
- }
-
- void LoadExplosionSprites(gamePtr game)
- /*
- This function loads all the graphics for the explosion sprites
- and also creates all of them. The game is limited to a fixed
- number of explosions happening at any one time.
- */
- {
- OSErr err;
- short ref;
- frameSetPtr expFrameSet;
- short i;
- short y;
-
- ref = OpenResFile("\pExplosionFrames.rsrc");
-
- err = CreateColorIconFrameSet(&expFrameSet, kBaseID, kMaxExpFrames);
- if(err != noErr) {
- ErrMsgCode("\pCreateColorIconFrameSet failed.",err);
- }
- if(err == noErr)
- SetFrameSetCTSeed(expFrameSet,game->gameCTSeed);
-
-
- err = CreateSpriteLayer(&gExplosionLayer,game->tween,game->backdrop,game->gameWind);
- if(err != noErr) {
- ErrMsgCode("\pCreateSpriteLayer failed.",err);
- }
-
- if(err == noErr) {
- err = CreateEmptySprite(gExplosionLayer,
- &gExplosionSprite[0], /* returned sprite here */
- kDefaultFrameAdvance,
- 0, /* time between movement */
- kExplosionFrameTime, /* time between frame change */
- (long)game); /* refcon, ptr to game */
-
- if(err != noErr) {
- ErrMsgCode("\pCreateEmptySprite failed.",err);
- } else {
- /* install the missile frame set */
- gExplosionSprite[0]->frameList = expFrameSet;
- }
- }
-
-
- for(i = 1; i < kMaxExp; i++) {
- if(err == noErr) {
- err = CreateEmptySprite(gExplosionLayer,
- &gExplosionSprite[i], /* returned sprite here */
- kDefaultFrameAdvance,
- 0, /* time between movement */
- kExplosionFrameTime, /* time between frame change */
- (long)game);
-
- if(err != noErr) {
- ErrMsgCode("\pCreateEmptySprite failed.",err);
- }
- }
-
- if(err == noErr) {
- /* dup the frame set */
- err = CopyFrameSet(expFrameSet, &gExplosionSprite[i]->frameList);
- if(err != noErr) {
- ErrMsgCode("\pCopyFrameSet failed!",err);
- }
- }
- }
-
- for(i = 0; i < kMaxExp; i++) {
- SetSpriteFrameCallback(gExplosionSprite[i],kFirstExpFrameNum,FirstFrameProc);
- SetSpriteFrameCallback(gExplosionSprite[i],kLastExpFrameNum,ExplosionLastFrameProc);
- SetSpriteFrameRef(gExplosionSprite[i],kLastExpFrameNum, i);
- gExplosionSprite[i]->inUse = false;
- }
-
- CloseResFile(ref);
-
- }
-